home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Programming / AmigaE / Src / Rkrm / Graphics_Libraries / Text / cliptext.e < prev    next >
Encoding:
Text File  |  1995-09-20  |  10.5 KB  |  262 lines

  1. -> cliptext.e
  2.  
  3. ->>> Header (globals)
  4. MODULE 'diskfont',
  5.        'layers',
  6.        'diskfont/diskfonttag',
  7.        'dos/rdargs',
  8.        'graphics/displayinfo',
  9.        'graphics/gfx',
  10.        'graphics/rastport',
  11.        'graphics/text',
  12.        'intuition/intuition',
  13.        'intuition/screens',
  14.        'utility/tagitem'
  15.  
  16. ENUM ERR_NONE, ERR_ARGS, ERR_FONT, ERR_KICK, ERR_LIB, ERR_OPEN, ERR_READ,
  17.      ERR_REGN, ERR_WIN
  18.  
  19. RAISE ERR_ARGS IF ReadArgs()=NIL,
  20.       ERR_FONT IF OpenDiskFont()=NIL,
  21.       ERR_KICK IF KickVersion()=FALSE,
  22.       ERR_LIB  IF OpenLibrary()=NIL,
  23.       ERR_OPEN IF Open()=NIL,
  24.       ERR_READ IF Read()<0,
  25.       ERR_REGN IF NewRegion()=NIL,
  26.       ERR_WIN  IF OpenWindowTagList()=NIL
  27.  
  28. CONST BUFSIZE=4096
  29.  
  30. ENUM FONT_NAME, FONT_SIZE, FILE_NAME, JAM_MODE, XASP, YASP, NUM_ARGS
  31.  
  32. CONST DEFAULTFONTSIZE=11, DEFAULTJAMMODE=0, DEFAULTXASP=0, DEFAULTYASP=0
  33.  
  34. DEF args:PTR TO LONG, tagitem[2]:ARRAY OF tagitem, buffer[BUFSIZE]:ARRAY,
  35.     myfile=NIL, mymsg:PTR TO intuimessage, mydrawinfo:PTR TO drawinfo,
  36.     mywin=NIL:PTR TO window, myrp:PTR TO rastport,
  37.     myfont=NIL:PTR TO textfont, myrectangle:rectangle, new_region=NIL
  38. ->>>
  39.  
  40. ->>> PROC main()
  41. PROC main() HANDLE
  42.   DEF myrda=NIL:PTR TO rdargs, mydi:displayinfo, mymodeid,
  43.       mydefaultfontsize=DEFAULTFONTSIZE,
  44.       mydefaultJAMMode=DEFAULTJAMMODE,
  45.       mydefaultXASP=DEFAULTXASP,  -> E-Note: C version fails to use these!
  46.       mydefaultYASP=DEFAULTYASP
  47.   args:=['topaz.font', {mydefaultfontsize}, 's:startup-sequence',
  48.          {mydefaultJAMMode}, {mydefaultXASP}, {mydefaultYASP}]
  49.   -> Run only on 2.0 machines
  50.   KickVersion(36)
  51.   -> dos.library standard command line parsing.  See the dos.library Autodoc
  52.   myrda:=ReadArgs('FontName,FontSize/N,FileName,Jam/N,XASP/N,YASP/N\n',
  53.                   args, NIL)
  54.   myfile:=Open(args[FILE_NAME], OLDFILE)  -> Open the file to display.
  55.   diskfontbase:=OpenLibrary('diskfont.library', 36)   -> Open the libraries.
  56.   layersbase:=OpenLibrary('layers.library', 36)
  57.   -> This application wants to hear about three things: 1) When the user
  58.   -> clicks the window's close gadget, 2) when the user starts to resize the
  59.   -> window, 3) and when the user has finished resizing the window.
  60.   mywin:=OpenWindowTagList(NIL,  -> Open that window.
  61.                           [WA_MINWIDTH,     100,
  62.                            WA_MINHEIGHT,    100,
  63.                            WA_SMARTREFRESH, TRUE,
  64.                            WA_SIZEGADGET,   TRUE,
  65.                            WA_CLOSEGADGET,  TRUE,
  66.                            WA_IDCMP, IDCMP_CLOSEWINDOW OR IDCMP_NEWSIZE OR
  67.                                           IDCMP_SIZEVERIFY,
  68.                            WA_DRAGBAR,      TRUE,
  69.                            WA_DEPTHGADGET,  TRUE,
  70.                            WA_TITLE,        args[FILE_NAME],
  71.                            TAG_END])
  72.   tagitem[0].tag:=OT_DEVICEDPI
  73.  
  74.   -> See if there is a non-zero value in the XASP or YASP fields.
  75.   -> Diskfont.library will get a divide by zero GURU if you give it a zero
  76.   -> XDPI or YDPI value.
  77.   -> If there is a zero value in one of them...
  78.   IF (Long(args[XASP])=0) OR (Long(args[YASP])=0)
  79.     -> ...use the aspect ratio of the current display as a default...
  80.     mymodeid:=GetVPModeID(mywin.wscreen.viewport)
  81.     IF GetDisplayInfoData(NIL, mydi, SIZEOF displayinfo, DTAG_DISP, mymodeid)
  82.       mydefaultXASP:=mydi.resolution.x
  83.       mydefaultYASP:=mydi.resolution.y
  84.       WriteF('XASP = \d    YAsp = \d\n', mydefaultXASP, mydefaultYASP)
  85.       -> Notice that the X and Y get _swapped_ to keep the look of the font
  86.       -> glyphs the same using screens with different aspect ratios.
  87.       args[YASP]:={mydefaultXASP}
  88.       args[XASP]:={mydefaultYASP}
  89.     ELSE
  90.       -> ...unless something is preventing us from getting the screens
  91.       -> resolution.  In that case, forget about the DPI tag.
  92.       tagitem[0].tag:=TAG_END
  93.     ENDIF
  94.   ENDIF
  95.   -> Here we have to put the X and Y DPI into the OT_DEVICEDPI tags data
  96.   -> field.  THESE ARE NOT REAL X AND Y DPI VALUES FOR THIS FONT OR THE
  97.   -> DISPLAY.  They only serve to supply the diskfont.library with values to
  98.   -> calculate the aspect ratio.  The X value gets stored in the upper word of
  99.   -> the tag value and the Y DPI gets stored in the lower word.  Because
  100.   -> ReadArgs() stores the _address_ of integers it gets from the command
  101.   -> line, you have to dereference the pointer it puts into the argument
  102.   -> array.
  103.   tagitem.data:=Shl(Long(args[XASP]), 16) OR Long(args[YASP])
  104.   tagitem.tag:=TAG_END
  105.  
  106.   -> Set up myfont to match the font the user requested.
  107.   myfont:=OpenDiskFont([args[FONT_NAME], Long(args[FONT_SIZE]),
  108.                         FSF_TAGGED, 0, tagitem]:ttextattr)  -> Open that font.
  109.   -> This is for the layers.library clipping region that gets attached to the
  110.   -> window.  This prevents the application from unnecessarily rendering
  111.   -> beyond the bounds of the inner part of the window.  For now, you can
  112.   -> ignore the layers stuff if you are just interested in learning about
  113.   -> using text.  For more information on clipping regions and layers, see the
  114.   -> Layers chapter of this manual.
  115.   myrectangle.minx:=mywin.borderleft
  116.   myrectangle.miny:=mywin.bordertop
  117.   myrectangle.maxx:=mywin.width-(mywin.borderright+1)
  118.   myrectangle.maxy:=mywin.height-(mywin.borderbottom+1)
  119.  
  120.   new_region:=NewRegion()
  121.   IF OrRectRegion(new_region, myrectangle)
  122.     InstallClipRegion(mywin.wlayer, new_region)
  123.     -> Obtain a pointer to the window's rastport and set up some of the
  124.     -> rastport attributes.  This example obtains the text pen for the
  125.     -> window's screen using GetScreenDrawInfo().
  126.     myrp:=mywin.rport
  127.     SetFont(myrp, myfont)
  128.     IF mydrawinfo:=GetScreenDrawInfo(mywin.wscreen)
  129.       SetAPen(myrp, mydrawinfo.pens[TEXTPEN])
  130.       FreeScreenDrawInfo(mywin.wscreen, mydrawinfo)
  131.     ENDIF
  132.     SetDrMd(myrp, Long(args[JAM_MODE]))
  133.  
  134.     mainLoop()
  135.   ENDIF
  136. EXCEPT DO
  137.   IF new_region THEN DisposeRegion(new_region)
  138.   IF myfont THEN CloseFont(myfont)
  139.   IF mywin THEN CloseWindow(mywin)
  140.   IF layersbase THEN CloseLibrary(layersbase)
  141.   IF diskfontbase THEN CloseLibrary(diskfontbase)
  142.   IF myfile THEN Close(myfile)
  143.   IF myrda THEN FreeArgs(myrda)
  144.   SELECT exception
  145.   CASE ERR_ARGS;  WriteF('Error: ReadArgs() failed\n')
  146.   CASE ERR_FONT;  WriteF('Error: could not open font\n')
  147.   CASE ERR_KICK;  WriteF('Error: requires V36+\n')
  148.   CASE ERR_LIB;   WriteF('Error: could not open required library\n')
  149.   CASE ERR_OPEN;  WriteF('Error: could not open file\n')
  150.   CASE ERR_READ;  WriteF('Error: Read() on the file failed\n')
  151.   CASE ERR_REGN;  WriteF('Error: could not allocate region\n')
  152.   CASE ERR_WIN;   WriteF('Error: could not open window\n')
  153.   ENDSELECT
  154. ENDPROC
  155. ->>>
  156.  
  157. ->>> PROC mainLoop()
  158. PROC mainLoop()
  159.   DEF count, actual, position, aok=TRUE, waitfornewsize=FALSE
  160.   -> E-Note: we don't need to find the task since we can use CtrlC()
  161.   Move(myrp, mywin.borderleft+1, mywin.bordertop+myfont.ysize+1)
  162.  
  163.   -> While there's something to read, fill the buffer
  164.   WHILE ((actual:=Read(myfile, buffer, BUFSIZE)) > 0) AND aok
  165.     position:=0
  166.     count:=0
  167.  
  168.     WHILE position<=actual
  169.       -> E-Note: logic swapped here...
  170.       IF waitfornewsize
  171.         WaitPort(mywin.userport)
  172.       ELSE
  173.         WHILE (buffer[count]>=myfont.lochar) AND 
  174.               (buffer[count]<=myfont.hichar) AND (count<=actual) DO INC count
  175.         Text(myrp, buffer+position, count-position)
  176.  
  177.         WHILE ((buffer[count]<myfont.lochar) OR
  178.                (buffer[count]>myfont.hichar)) AND (count<=actual)
  179.           IF buffer[count]=$0A
  180.             Move(myrp, mywin.borderleft, myrp.cp_y+myfont.ysize+1)
  181.           ENDIF
  182.           INC count
  183.         ENDWHILE
  184.         position:=count
  185.       ENDIF
  186.  
  187.       WHILE mymsg:=GetMsg(mywin.userport)
  188.         -> The user clicked the close gadget.
  189.         IF mymsg.class=IDCMP_CLOSEWINDOW
  190.           aok:=FALSE
  191.           position:=actual+1
  192.           ReplyMsg(mymsg)
  193.         -> The user picked up the window's sizing gagdet.
  194.         ELSEIF mymsg.class=IDCMP_SIZEVERIFY
  195.           -> When the user has picked up the window's sizing gadget when the
  196.           -> IDCMP_SIZEVERIFY flag is set, the application has to reply to
  197.           -> this message to tell Intuition to allow the user to move the
  198.           -> sizing gadget and resize the window.  The reason for using this
  199.           -> here is because the user can resize the window while cliptext.e
  200.           -> is rendering text to the window.  Cliptext.e has to stop
  201.           -> rendering text when it receives an IDCMP_SIZEVERIFY message.
  202.           ->
  203.           -> If this example had instead asked to hear about IDCMP events that
  204.           -> could take place between SIZEVERIFY and NEWSIZE events
  205.           -> (especially INTUITICKS), it should turn off those events here
  206.           -> using ModifyIDCMP().
  207.           ->
  208.           -> After we allow the user to resize the window, we cannot write
  209.           -> into the window until the user has finished resizing it because
  210.           -> we need the window's new size to adjust the clipping area. 
  211.           -> Specifically, we have to wait for an IDCMP_NEWSIZE message which
  212.           -> Intuition will send when the user lets go of the resize gadget. 
  213.           -> For now, we set the waitfornewsize flag to stop rendering until
  214.           -> we get that NEWSIZE message.
  215.           waitfornewsize:=TRUE
  216.           WaitBlit()
  217.           -> The blitter is done, let the user resize the window
  218.           ReplyMsg(mymsg)
  219.         ELSE
  220.           ReplyMsg(mymsg)
  221.           waitfornewsize:=FALSE
  222.           -> The user has resized the window, so get the new window dimensions
  223.           -> and readjust the layers clipping region accordingly.
  224.           myrectangle.minx:=mywin.borderleft
  225.           myrectangle.miny:=mywin.bordertop
  226.           myrectangle.maxx:=mywin.width-(mywin.borderright+1)
  227.           myrectangle.maxy:=mywin.height-(mywin.borderbottom+1)
  228.           InstallClipRegion(mywin.wlayer, NIL)
  229.           ClearRegion(new_region)
  230.           IF OrRectRegion(new_region, myrectangle)
  231.             InstallClipRegion(mywin.wlayer, new_region)
  232.           ELSE
  233.             aok:=FALSE
  234.             position:=actual+1
  235.           ENDIF
  236.         ENDIF
  237.       ENDWHILE
  238.       IF CtrlC()  -> Check for user break.
  239.         aok:=FALSE
  240.         position:=actual+1
  241.       ENDIF
  242.  
  243.       -> If we reached the bottom of the page, clear the rastport and move
  244.       -> back to the top.
  245.       IF myrp.cp_y>(mywin.height-(mywin.borderbottom+2))
  246.         Delay(25)
  247.  
  248.         -> Set the entire rastport to colour zero.  This will not include the
  249.         -> window borders because of the layers clipping.
  250.         SetRast(myrp, 0)
  251.         Move(myrp, mywin.borderleft+1, mywin.bordertop+myfont.ysize+1)
  252.       ENDIF
  253.     ENDWHILE
  254.   ENDWHILE
  255. ENDPROC
  256. ->>>
  257.  
  258. ->>> Version string
  259. vers:
  260.   CHAR 0, '$VER: cliptext 37.2', 0
  261. ->>>
  262.